from datetime import datetime, timedelta
from flask import current_app, redirect, url_for,request
import jwt
import requests
from app.src.user.dao import UserDAO
from app.utils.security import verify_password
from app.config import Config

class AuthService:
    def __init__(self):
        self.user_dao = UserDAO()
        self.sso_config = {
            'sso_server': Config.SSO_SERVER_URL,
            'sso_inner_server': Config.SSO_SERVER_INNER_URL,
            'client_id': Config.SSO_CLIENT_ID,
            'client_secret': Config.SSO_CLIENT_SECRET,
            'redirect_uri': Config.SSO_REDIRECT_URI
        }

    def login(self, code=None):
        """SSO登录处理"""
        if not code:
            # 重定向到 SSO 服务器
            return {
                'success': False,
                'redirect_url': f"{self.sso_config['sso_server']}/oauth/authorize?"
                               f"client_id={self.sso_config['client_id']}&"
                               f"redirect_uri={self.sso_config['redirect_uri']}&"
                               f"response_type=code"
            }

        try:
            current_app.logger.error(f"{self.sso_config['sso_inner_server']}/oauth/token")
            current_app.logger.error({
                    'grant_type': 'authorization_code',
                    'code': code,
                    'client_id': self.sso_config['client_id'],
                    'client_secret': self.sso_config['client_secret'],
                    'redirect_uri': self.sso_config['redirect_uri']
                })
            # 使用授权码获取访问令牌
            token_response = requests.post(
                f"{self.sso_config['sso_inner_server']}/oauth/token",
                data={
                    'grant_type': 'authorization_code',
                    'code': code,
                    'client_id': self.sso_config['client_id'],
                    'client_secret': self.sso_config['client_secret'],
                    'redirect_uri': self.sso_config['redirect_uri']
                }
            )

            print(token_response)
            token_data = token_response.json()

            if 'access_token' not in token_data:
                return {
                    'success': False,
                    'message': 'SSO认证失败'
                }

            # 获取用户信息
            user_response = requests.get(
                f"{self.sso_config['sso_inner_server']}/oauth/userinfo",
                headers={'Authorization': f"Bearer {token_data['access_token']}"}
            )
            user_info = user_response.json()

            # 检查用户是否存在，不存在则创建
            # user = self.user_dao.get_user_by_username(user_info['username'])
            # if not user:
            #     user_data = {
            #         'username': user_info['username'],
            #         'name': user_info.get('name', ''),
            #         'email': user_info.get('email', ''),
            #         'role': 'user'  # 默认角色
            #     }
            #     user_id = self.user_dao.create_user(user_data)
            #     user = self.user_dao.get_user_by_id(user_id)

            # 生成应用系统的 JWT token
            user = user_info
            token = self._generate_token(user,token_data)
            
            return {
                'success': True,
                'token': token,
                'user_info': {
                    'id':user.get('id'),
                    'account': user.get('account'),
                    'username': user.get('username'),
                    'phone_number': user.get('phone_number'),
                    'email': user.get('email')
                }
            }

        except Exception as e:
            current_app.logger.error(f"SSO登录失败: {str(e)}")
            return {
                'success': False,
                'message': 'SSO登录失败'
            }

    def logout(self):
        """退出登录，包括SSO退出"""
        try:
            # 获取当前请求的 token
            token = request.headers.get('Authorization')
            if token:
                pass

            
            return {
                'success': True,
                'message': '退出成功',
                'sso_logout_url':f"{self.sso_config['sso_server']}/oauth/logout"
            }
        except Exception as e:
            current_app.logger.error(f"退出失败: {str(e)}")
            return {
                'success': False,
                'message': '退出失败'
            }
    
    def verify_token(self, token):
        try:
            payload = jwt.decode(
                token,
                current_app.config['SECRET_KEY'],
                algorithms=['HS256']
            )
            
            # user = self.user_dao.get_user_by_id(payload.get('user_id'))
            user_response = requests.get(
                f"{self.sso_config['sso_inner_server']}/oauth/userinfo",
                headers={'Authorization': f"Bearer {payload['token_data']['access_token']}"}
            )
            print(f"{self.sso_config['sso_inner_server']}/oauth/userinfo")
            print(f"Bearer {payload['token_data']['access_token']}")

            if user_response.status_code == 401:
                return {'valid': False, 'message': 'Token已失效'}

            user = user_response.json()
            
            return {
                'valid': True,
                'user_info': {
                    'id': user.get('id'),
                    'username': user.get('username'),
                    'account': user.get('account'),
                    'phone_number': user.get('phone_number'),
                    'email': user.get('email')
                }
            }
        except jwt.ExpiredSignatureError:
            return {'valid': False, 'message': 'Token已过期'}
        except jwt.InvalidTokenError:
            return {'valid': False, 'message': 'Token无效'}
    
    def _generate_token(self, user,token_data):
        now = datetime.utcnow()
        payload = {
            'user_id': user.get('id'),
            'token_data': token_data,
            'exp': now + timedelta(hours=24),
            'iat': now
        }
        return jwt.encode(
            payload,
            current_app.config['SECRET_KEY'],
            algorithm='HS256'
        )